﻿using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Core
{
    public class Wordlist
    {
        public List<string> Words { get; private set; }
        public Dictionary<string, bool> WordDic { get; private set; }
        private Dictionary<string, IEnumerable<string>> _cache;

        public Wordlist(string pathToDictionary)
        {
            var file = new StreamReader(pathToDictionary);
            Words = new List<string>();
            while (!file.EndOfStream)
            {
                string word = file.ReadLine().ToUpper();
                Words.Add(word);
            }
            file.Close();
            UpdateCache();
        }

        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }

        public Wordlist(params string[] words)
        {
            Words = new List<string>(words);
            UpdateCache();
        }

        public void UpdateCache()
        {
            _cache = new Dictionary<string, IEnumerable<string>>();
            for (int i = 65; i <= 90; i++)
            {
                for (int j = 65; j <= 90; j++)
                {
                    string starts = ((char)i).ToString() + (char)j;
                    var matches = Words.Where(s => s.StartsWith(starts));
                    _cache.Add(starts, matches);
                }
            }
            WordDic = new Dictionary<string, bool>();
            foreach (string s in Words)
            {
                if (!WordDic.ContainsKey(s))
                    WordDic.Add(s, false);
            }
        }

        public IEnumerable<string> StartsWith(string starts)
        {
            string key = starts[0].ToString() + starts[1];
            if (_cache.ContainsKey(key))
            {
                foreach (string k in _cache[key].Where(s => s.StartsWith(starts)))
                {
                    yield return k;
                }
            }
            yield break;
        }

        public IEnumerable<string> ValidMovesFor(string starts)
        {
            return StartsWith(starts).Where(s => s.Length > starts.Length)
                                     .Select(s => s[starts.Length].ToString())
                                     .Distinct();
        }

        public bool IsWholeWord(string search)
        {
            return WordDic.ContainsKey(search);
        }
    }
}
